﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WSCeCommerce.Helpers;

namespace WSCeCommerce.Tests.Controllers
{
    /// <summary>
    /// Base class used for controllers that need to create and delete items
    /// </summary>
    /// <typeparam name="T"></typeparam>
     public abstract class ControllerTestBase<T> where T :class
    {

        private List<T> _deleteList;
        WSCeCommerceDBContext _context;

        [TestInitialize]
        public void Init()
        {
            _deleteList = new List<T>();
            _context = new WSCeCommerceDBContext();
        }

        [TestCleanup]
        public void Cleanup()
        {
            if (_deleteList.Count > 0)
            {
                //Delete all created categories
                foreach (T obj in _deleteList)
                {
                    T found = FindInDatabase(obj);
                    if (found != null)
                    {
                        DbSet.Remove(found);
                    }
                }
                _context.SaveChanges();
            }
        }


         /// <summary>
         /// Database context to be used  during the test
         /// </summary>
        protected WSCeCommerceDBContext Context { 
            get { return _context; }
        }

         /// <summary>
         /// List of items to delete at the end of the test
         /// </summary>
        protected List<T> DeleteList
        {
            get { return _deleteList; }
        }

         /// <summary>
         /// Find the desired object in the database. Default implemententation calls GetKey() and DbSet.Find()
         /// </summary>
         /// <param name="obj">Object to find in the database</param>
         /// <returns>Object found in database. If the object can not be found, null we be returned</returns>
        protected virtual T FindInDatabase(T obj)
        {
            int key = GetKey(obj);
            T found = DbSet.Find(key);
            return found;
        }

         /// <summary>
         /// DbSet used to delete entries from
         /// </summary>
         protected abstract DbSet<T> DbSet{get;}

         /// <summary>
         /// Get the key of the desired object. This is used during the delete phase
         /// </summary>
         /// <param name="obj">Object to get the key for</param>
         /// <returns>Database key of the desired object</returns>
         protected abstract int GetKey(T obj);

    }
}
